﻿namespace TestTool.GUI.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.ServiceModel;
    using System.Text;
    using System.Windows.Forms;
    using System.Xml.Serialization;
    using TestTool.GUI.Data;
    using TestTool.GUI.Data.Log;
    using TestTool.GUI.Enums;
    using TestTool.GUI.SilentProcessing;
    using TestTool.GUI.Utils;
    using TestTool.GUI.Utils.Profiles;
    using TestTool.GUI.Views;
    using TestTool.Tests.Common.TestEngine;
    using TestTool.Tests.Definitions.Attributes;
    using TestTool.Tests.Definitions.Data;
    using TestTool.Tests.Definitions.Enums;
    using TestTool.Tests.Definitions.Interfaces;
    using TestTool.Tests.Definitions.Trace;
    using TestTool.Tests.Definitions.UI;
    using TestTool.Tests.Engine;

    internal class TestController : Controller<ITestView>
    {
        private bool _conformance;
        private Dictionary<Guid, SettingsTabPage> _controls;
        protected TestResult _featureDefinitionLog;
        private ConformanceInitializationData _initializationData;
        private List<IProfileDefinition> _onvifProfiles;
        private StringBuilder _plainTextLog;
        private Dictionary<IProfileDefinition, ProfileTestInfo> _profilesSupportInfo;
        protected bool _running;
        private bool _runningSingle;
        private bool _scrollingEnabled;
        private List<System.Type> _settingsTypes;
        private StringBuilder _shortTestLog;
        protected TestDispatcher _td;
        protected DateTime _testExecutionTime;
        private List<TestInfo> _testInfos;
        protected Dictionary<TestInfo, TestResult> _testResults;
        private int _testsCount;
        private List<TestInfo> _testsSupported;
        private TestResult _testSteps;

        public event Action<ConformanceInitializationData> ConformanceInitializationCompleted;

        public event Action<DeviceInfo> DeviceInfoReceived;

        public event Action<List<SettingsTabPage>> SettingPagesLoaded;

        public event Action<TestInfo, TestTool.Tests.Definitions.Trace.TestLog> TestCompleted;

        public event Action TestsCleared;

        public event Action<TestInfo> TestStarted;

        public event Action<bool> TestSuiteCompleted;

        public event Action<TestSuiteParameters, bool> TestSuiteStarted;

        public TestController(ITestView view) : base(view)
        {
            this._scrollingEnabled = true;
            this._profilesSupportInfo = new Dictionary<IProfileDefinition, ProfileTestInfo>();
            this._testResults = new Dictionary<TestInfo, TestResult>();
            this._td = new TestDispatcher();
            this._td.TestStarted += new Action<TestInfo>(this._td_TestStarted);
            this._td.TestCompleted += new TestDispatcher.TestCompletedHandler(this._td_TestCompleted);
            this._td.StepStarted += new Action<StepResult>(this._td_StepStarted);
            this._td.StepCompleted += new StepCompleted(this._td_StepCompleted);
            this._td.RequestSent += new Action<string>(this._td_RequestSent);
            this._td.ResponseReceived += new Action<string>(this._td_ResponseReceived);
            this._td.OnException += new Action<Exception>(this._td_OnException);
            this._td.StepEvent += new Action<string>(this._td_StepEvent);
            this._td.TestEvent += new Action<string>(this._td_TestEvent);
            this._td.Paused += new Action(this._td_Paused);
            this._td.FeatureDefined += new Action<Feature, bool>(this._td_FeatureDefined);
            this._td.FeatureDefinitionFailed += new Action<Feature>(this._td_FeatureDefinitionFailed);
            this._td.InitializationCompleted += new Action<ConformanceInitializationData>(this._td_InitializationCompleted);
            this._td.DeviceInformationReceived += new Action<TestTool.Tests.Engine.DeviceInformation>(this._td_DeviceInformationReceived);
            this._td.ProfileDefinitionCompleted += new TestDispatcher.ProfileDefinitionCompletedHandler(this._td_ProfileDefinitionCompleted);
            this._td.TestSuiteCompleted += new Action<TestSuiteParameters, bool>(this._td_TestSuiteCompleted);
        }

        private void _td_DeviceInformationReceived(TestTool.Tests.Engine.DeviceInformation data)
        {
            if (this._conformance && (this.DeviceInfoReceived != null))
            {
                DeviceInfo info = new DeviceInfo {
                    FirmwareVersion = data.FirmwareVersion,
                    HardwareID = data.HardwareID,
                    Manufacturer = data.Manufacturer,
                    Model = data.Model,
                    SerialNumber = data.SerialNumber
                };
                this.DeviceInfoReceived(info);
            }
        }

        private void _td_FeatureDefined(Feature feature, bool supported)
        {
            if (base.View.FeaturesView != null)
            {
                base.View.FeaturesView.DisplayFeature(feature, supported);
            }
        }

        private void _td_FeatureDefinitionFailed(Feature feature)
        {
            if (base.View.FeaturesView != null)
            {
                base.View.FeaturesView.DisplayUndefinedFeature(feature);
            }
        }

        private void _td_InitializationCompleted(ConformanceInitializationData data)
        {
            this._testsSupported = data.TestsSelected;
            this._initializationData = data;
            if (data.Continue && (base.View.TestTreeView != null))
            {
                base.View.TestTreeView.SelectTests(data.TestsSelected);
            }
            if (this.ConformanceInitializationCompleted != null)
            {
                this.ConformanceInitializationCompleted(data);
            }
            this.DisplayFunctionalitySupport(data.TestsSelected);
            if (base.View.ProfilesView != null)
            {
                base.View.ProfilesView.DisplayProfiles(data.SupportedProfiles, data.FailedProfiles, data.UnsupportedProfiles);
            }
        }

        private void _td_OnException(Exception exc)
        {
            StringBuilder builder = new StringBuilder("Inner exception: " + Environment.NewLine);
            Exception innerException = exc;
            for (string str = string.Empty; innerException != null; str = str + "   ")
            {
                builder.AppendFormat("{0}{1}{2}", str, innerException.Message, Environment.NewLine);
                innerException = innerException.InnerException;
            }
            string entry = builder.ToString();
            this.WriteLog(entry, LogEntryLevel.Test);
        }

        private void _td_Paused()
        {
            base.View.SwitchToState(TestTool.GUI.Enums.ApplicationState.TestPaused);
        }

        private void _td_ProfileDefinitionCompleted(IProfileDefinition profile, ProfileStatus status, string dump)
        {
            ProfileTestInfo info = new ProfileTestInfo {
                Status = status,
                Log = dump
            };
            if (this._profilesSupportInfo.ContainsKey(profile))
            {
                this._profilesSupportInfo[profile] = info;
            }
            else
            {
                this._profilesSupportInfo.Add(profile, info);
            }
        }

        private void _td_RequestSent(string request)
        {
            string entry = "Transmit done";
            this.WriteLog(entry, LogEntryLevel.StepDetails);
        }

        private void _td_ResponseReceived(string obj)
        {
            string entry = "Receive done";
            this.WriteLog(entry, LogEntryLevel.StepDetails);
        }

        private void _td_StepCompleted(StepResult result)
        {
            FaultException exception = result.Exception as FaultException;
            bool flag = false;
            if (exception != null)
            {
                flag = true;
            }
            string entry = string.Format("STEP {0}", result.Status.ToString().ToUpper());
            if ((result.Status == StepStatus.Failed) && !flag)
            {
                this.WriteLog(result.Message, LogEntryLevel.StepDetails);
            }
            this.WriteLog(entry, LogEntryLevel.Step);
            this.WriteLog(string.Empty, LogEntryLevel.Test);
            this._testSteps.Log.Steps.Add(result);
            this.DisplayStepResult(result);
        }

        private void _td_StepEvent(string obj)
        {
            this.WriteLog(obj, LogEntryLevel.StepDetails);
        }

        private void _td_StepStarted(StepResult result)
        {
            string entry = string.Format("STEP {0} - {1}", result.Number, result.StepName);
            this.WriteLog(entry, LogEntryLevel.Step);
        }

        private void _td_TestCompleted(TestInfo testInfo, TestTool.Tests.Definitions.Trace.TestLog log)
        {
            bool flag = testInfo.ProcessType == ProcessType.Test;
            bool flag2 = (this._runningSingle || base.View.Repeat) && this._testResults.ContainsKey(testInfo);
            TestResult result = new TestResult {
                Log = log,
                TestInfo = testInfo
            };
            if (!string.IsNullOrEmpty(log.ErrorMessage))
            {
                string str = string.Format("   Error: {0}{1}", log.ErrorMessage, Environment.NewLine);
                this.WriteLog(str, LogEntryLevel.Test);
            }
            string entry = string.Empty;
            if (result.Log.TestStatus == TestStatus.NotSupported)
            {
                entry = "DEVICE FEATURE NOT SUPPORTED BY THE NVT";
            }
            else if (flag)
            {
                entry = string.Format("TEST {0}", result.Log.TestStatus.ToString().ToUpper());
            }
            else
            {
                entry = "PROCESS COMPLETED";
            }
            this.WriteLog(entry, LogEntryLevel.Test);
            result.PlainTextLog = this._plainTextLog.ToString();
            result.ShortTextLog = this._shortTestLog.ToString();
            if (flag)
            {
                if (flag2)
                {
                    this._testResults[testInfo] = result;
                }
                else
                {
                    this._testResults.Add(testInfo, result);
                }
                base.View.EndTest(this._testResults[testInfo]);
            }
            else
            {
                this._featureDefinitionLog = result;
                base.View.EndTest(this._featureDefinitionLog);
            }
            if (this.TestCompleted != null)
            {
                this.TestCompleted(testInfo, log);
            }
        }

        private void _td_TestEvent(string obj)
        {
            this.WriteLog(obj, LogEntryLevel.Step);
        }

        private void _td_TestStarted(TestInfo testInfo)
        {
            base.View.BeginTest(testInfo);
            if (this._scrollingEnabled)
            {
                base.View.TestResultView.BeginTest();
            }
            this._plainTextLog = new StringBuilder();
            this._shortTestLog = new StringBuilder();
            this._testSteps = new TestResult();
            this._testSteps.Log = new TestTool.Tests.Definitions.Trace.TestLog();
            this.WriteLog(testInfo.Name, LogEntryLevel.Test);
            this.WriteLog(string.Empty, LogEntryLevel.Test);
            if (this.TestStarted != null)
            {
                this.TestStarted(testInfo);
            }
        }

        private void _td_TestSuiteCompleted(TestSuiteParameters parameters, bool bCompletedNormally)
        {
            if (bCompletedNormally && !this._conformance)
            {
                this.ReportTestSuiteCompleted();
            }
            this.CompleteTestSuite(parameters, bCompletedNormally);
            if (this.TestSuiteCompleted != null)
            {
                this.TestSuiteCompleted(bCompletedNormally);
            }
            this._running = false;
        }

        public void ApplyProfile(Profile profile)
        {
            if (base.View.TestTreeView != null)
            {
                base.View.TestTreeView.ApplyProfileOptions(profile);
            }
        }

        public void Clear(bool bAllResults)
        {
            this._testResults.Clear();
            base.View.ClearTestResults();
            if (bAllResults)
            {
                this.ClearFeatures();
                this._testsSupported = null;
                this._profilesSupportInfo.Clear();
            }
            else if (this._testsSupported != null)
            {
                this.DisplayFunctionalitySupport(this._testsSupported);
            }
            if (this.TestsCleared != null)
            {
                this.TestsCleared();
            }
        }

        public void ClearFeatures()
        {
            this._featureDefinitionLog = null;
            this._td.ResetFeatures();
            if (base.View.FeaturesView != null)
            {
                base.View.FeaturesView.Clear();
            }
        }

        private void CompleteTestSuite(TestSuiteParameters parameters, bool bCompletedNormally)
        {
            if (bCompletedNormally)
            {
                if (parameters.DefineProfiles)
                {
                    Dictionary<TestInfo, TestStatus> log = new Dictionary<TestInfo, TestStatus>();
                    foreach (TestInfo info in this._testResults.Keys)
                    {
                        log.Add(info, this._testResults[info].Log.TestStatus);
                    }
                    if (base.View.ProfilesView != null)
                    {
                        Dictionary<Functionality, bool> functionality = ProfilesSupportInfo.CheckTestResults(log);
                        base.View.ProfilesView.DisplaySupportedFunctionality(functionality);
                    }
                    bool flag = (from TR in this._testResults.Values
                        where TR.Log.TestStatus == TestStatus.Failed
                        select TR).Count<TestResult>() > 0;
                    List<IProfileDefinition> failed = new List<IProfileDefinition>();
                    List<IProfileDefinition> supported = new List<IProfileDefinition>();
                    if (flag)
                    {
                        failed.AddRange(this._initializationData.FailedProfiles);
                        failed.AddRange(this._initializationData.SupportedProfiles);
                    }
                    else
                    {
                        supported.AddRange(this._initializationData.SupportedProfiles);
                    }
                    if (base.View.ProfilesView != null)
                    {
                        base.View.ProfilesView.DisplayProfiles(supported, failed, this._initializationData.UnsupportedProfiles);
                    }
                }
                this.UpdateTestLog();
            }
        }

        public void DefineFeatures(TestSuiteParameters parameters)
        {
            parameters.FeatureDefinition = FeatureDefinitionMode.Define;
            this.RunDiagnostic(parameters, true);
        }

        private void DisplayFunctionalitySupport(IEnumerable<TestInfo> tests)
        {
            if (base.View.ProfilesView != null)
            {
                List<Feature> features = new List<Feature>(this._td.Features);
                features.AddRange(this._td.UndefinedFeatures);
                ProfilesSupportInfo info = ProfilesSupportInfo.LoadPreliminary(this._onvifProfiles, this._testInfos, tests, features);
                base.View.ProfilesView.DisplayFunctionalityWithoutTestsInSuite(info.FunctionalityWithoutTests);
                base.View.ProfilesView.DisplayFunctionalityToBeTested(info.FunctionalityUnderTests);
                base.View.ProfilesView.DisplayMandatoryFunctionalityWithoutFeatures(info.MandatoryFunctionalityWithoutFeatures);
                base.View.ProfilesView.DisplayOptionalFunctionalityWithoutFeatures(info.OptionalFunctionalityUnderSkippedTests);
                this.DisplayProfileScopes();
            }
        }

        private void DisplayLogLine(string line)
        {
            if (this._scrollingEnabled && (base.View.TestResultView != null))
            {
                base.View.TestResultView.WriteLine(line);
            }
        }

        private void DisplayProfileScopes()
        {
            if (base.View.ProfilesView != null)
            {
                List<string> list = new List<string>();
                foreach (IProfileDefinition definition in this._onvifProfiles)
                {
                    foreach (string str in definition.MandatoryScopes)
                    {
                        if (!list.Contains(str))
                        {
                            list.Add(str);
                        }
                    }
                }
                foreach (string str2 in list)
                {
                    base.View.ProfilesView.DisplayScope(str2, this._td.Scopes.Contains(str2));
                }
            }
        }

        private void DisplayStepResult(StepResult result)
        {
            if (this._scrollingEnabled && (base.View.TestResultView != null))
            {
                base.View.TestResultView.DisplayStepResult(result);
            }
        }

        public void EnableScrolling(bool enable)
        {
            this._scrollingEnabled = enable;
        }

        public void Exit()
        {
            this._td.Shutdown();
        }

        public TestResult GetCurrentLog()
        {
            this._testSteps.PlainTextLog = this._plainTextLog.ToString();
            return this._testSteps;
        }

        public TestResult GetFeaturesDefinitionLog()
        {
            return this._featureDefinitionLog;
        }

        public TestSuiteParameters GetParameters()
        {
            TestSuiteParameters parameters = new TestSuiteParameters();
            DiscoveredDevices discoveredDevices = ContextController.GetDiscoveredDevices();
            parameters.Address = discoveredDevices.ServiceAddress;
            parameters.CameraIP = discoveredDevices.DeviceAddress;
            parameters.NetworkInterfaceController = discoveredDevices.NIC;
            if ((discoveredDevices.Current != null) && (discoveredDevices.Current.ByDiscovery != null))
            {
                parameters.CameraUUID = discoveredDevices.Current.ByDiscovery.UUID;
            }
            DeviceEnvironment deviceEnvironment = ContextController.GetDeviceEnvironment();
            parameters.UserName = deviceEnvironment.Credentials.UserName;
            parameters.Password = deviceEnvironment.Credentials.Password;
            parameters.UseUTCTimestamp = deviceEnvironment.Credentials.UseUTCTimeStamp;
            parameters.MessageTimeout = deviceEnvironment.Timeouts.Message;
            parameters.RebootTimeout = deviceEnvironment.Timeouts.Reboot;
            parameters.TimeBetweenTests = deviceEnvironment.Timeouts.InterTests;
            parameters.OperationDelay = deviceEnvironment.TestSettings.OperationDelay;
            parameters.RecoveryDelay = deviceEnvironment.TestSettings.RecoveryDelay;
            parameters.RetentionTime = deviceEnvironment.TestSettings.RetentionTime;
            parameters.RepeatTests = base.View.Repeat;
            TestTool.Tests.Common.TestEngine.EnvironmentSettings settings = new TestTool.Tests.Common.TestEngine.EnvironmentSettings {
                DnsIpv4 = deviceEnvironment.EnvironmentSettings.DnsIpv4,
                NtpIpv4 = deviceEnvironment.EnvironmentSettings.NtpIpv4,
                DnsIpv6 = deviceEnvironment.EnvironmentSettings.DnsIpv6,
                NtpIpv6 = deviceEnvironment.EnvironmentSettings.NtpIpv6,
                DefaultGateway = deviceEnvironment.EnvironmentSettings.GatewayIpv4,
                DefaultGatewayIpv6 = deviceEnvironment.EnvironmentSettings.GatewayIpv6
            };
            parameters.EnvironmentSettings = settings;
            parameters.PTZNodeToken = deviceEnvironment.TestSettings.PTZNodeToken;
            parameters.UseEmbeddedPassword = deviceEnvironment.TestSettings.UseEmbeddedPassword;
            parameters.Password1 = deviceEnvironment.TestSettings.Password1;
            parameters.Password2 = deviceEnvironment.TestSettings.Password2;
            parameters.SecureMethod = deviceEnvironment.TestSettings.SecureMethod;
            parameters.VideoSourceToken = deviceEnvironment.TestSettings.VideoSourceToken;
            parameters.EventTopic = deviceEnvironment.TestSettings.EventTopic;
            parameters.SubscriptionTimeout = deviceEnvironment.TestSettings.SubscriptionTimeout;
            parameters.TopicNamespaces = deviceEnvironment.TestSettings.TopicNamespaces;
            parameters.RelayOutputDelayTimeMonostable = deviceEnvironment.TestSettings.RelayOutputDelayTimeMonostable;
            parameters.RecordingToken = deviceEnvironment.TestSettings.RecordingToken;
            parameters.SearchTimeout = deviceEnvironment.TestSettings.SearchTimeout;
            parameters.MetadataFilter = deviceEnvironment.TestSettings.MetadataFilter;
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            foreach (object obj2 in deviceEnvironment.TestSettings.AdvancedSettings)
            {
                dictionary.Add(obj2.GetType().GUID.ToString(), obj2);
            }
            parameters.AdvancedParameters = dictionary;
            parameters.VideoForm = base.View.GetVideoForm();
            parameters.Operator = new Operator(base.View.Window);
            return parameters;
        }

        public ProfileTestInfo GetProfileInformation(IProfileDefinition profile)
        {
            if (this._profilesSupportInfo.ContainsKey(profile))
            {
                return this._profilesSupportInfo[profile];
            }
            return null;
        }

        public TestResult GetTestResult(TestInfo testInfo)
        {
            if (this._testResults.ContainsKey(testInfo))
            {
                return this._testResults[testInfo];
            }
            return null;
        }

        public void Halt()
        {
            this._td.Halt();
        }

        public bool HasTestResults()
        {
            return (this._testResults.Count > 0);
        }

        public override void Initialize()
        {
            base.Initialize();
            this.LoadTests();
        }

        protected void InternalRun(TestSuiteParameters parameters, bool single, bool conformance)
        {
            this._running = true;
            this.EnableScrolling(true);
            if (!single)
            {
                this._testResults.Clear();
                this._testExecutionTime = DateTime.Now;
            }
            if (parameters.FeatureDefinition == FeatureDefinitionMode.Define)
            {
                this._testResults.Clear();
            }
            this._conformance = conformance;
            this._runningSingle = single;
            this.ReportTestSuiteStarted(parameters, conformance);
            if (parameters.FeatureDefinition == FeatureDefinitionMode.Define)
            {
                this._td.RequestFeatures(parameters);
            }
            else
            {
                this._td.Run(parameters);
            }
        }

        private void LoadProfile(System.Type t)
        {
            if (t.GetInterfaces().Contains<System.Type>(typeof(IProfileDefinition)))
            {
                IProfileDefinition item = (IProfileDefinition) Activator.CreateInstance(t, new object[0]);
                this._onvifProfiles.Add(item);
            }
        }

        public List<TestInfo> LoadTests()
        {
            this._testInfos = new List<TestInfo>();
            this._onvifProfiles = new List<IProfileDefinition>();
            this._controls = new Dictionary<Guid, SettingsTabPage>();
            this._settingsTypes = new List<System.Type>();
            Dictionary<System.Type, System.Type> dictionary = new Dictionary<System.Type, System.Type>();
            foreach (string str3 in Directory.GetFiles(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "*.dll"))
            {
                try
                {
                    Assembly assembly = Assembly.LoadFile(str3);
                    if (assembly.GetCustomAttributes(typeof(TestAssemblyAttribute), false).Length > 0)
                    {
                        foreach (System.Type type in assembly.GetTypes())
                        {
                            if (type.GetCustomAttributes(typeof(TestClassAttribute), true).Length > 0)
                            {
                                this.LoadTests(type);
                            }
                            if (type.GetCustomAttributes(typeof(ProfileDefinitionAttribute), true).Length > 0)
                            {
                                this.LoadProfile(type);
                            }
                            object[] customAttributes = type.GetCustomAttributes(typeof(SettingsControlAttribute), true);
                            if (customAttributes.Length > 0)
                            {
                                SettingsControlAttribute attribute = (SettingsControlAttribute) customAttributes[0];
                                if (!dictionary.ContainsKey(attribute.ParametersType))
                                {
                                    dictionary.Add(attribute.ParametersType, type);
                                }
                            }
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
            foreach (System.Type type2 in this._settingsTypes)
            {
                System.Type type3 = dictionary[type2];
                object obj2 = Activator.CreateInstance(type3);
                SettingsTabPage page = (SettingsTabPage) obj2;
                page.Dock = DockStyle.Fill;
                this._controls.Add(type2.GUID, (SettingsTabPage) obj2);
            }
            if (this.SettingPagesLoaded != null)
            {
                this.SettingPagesLoaded(this._controls.Values.ToList<SettingsTabPage>());
            }
            if (base.View.TestTreeView != null)
            {
                base.View.TestTreeView.DisplayTests(this._testInfos);
            }
            if (base.View.ProfilesView != null)
            {
                base.View.ProfilesView.DisplayProfiles(from P in this._onvifProfiles
                    orderby P.Name
                    select P);
            }
            return this._testInfos;
        }

        private void LoadTests(System.Type t)
        {
            if (t.GetInterfaces().Contains<System.Type>(typeof(ITest)))
            {
                foreach (MethodInfo info in t.GetMethods())
                {
                    if (info.DeclaringType == t)
                    {
                        object[] customAttributes = info.GetCustomAttributes(typeof(TestAttribute), true);
                        if (customAttributes.Length > 0)
                        {
                            TestAttribute attribute = (TestAttribute) customAttributes[0];
                            TestInfo item = (from ti in this._testInfos
                                where (ti.Id == attribute.Id) && (ti.Category == attribute.Category)
                                select ti).FirstOrDefault<TestInfo>();
                            if (item != null)
                            {
                                if (item.Version > attribute.Version)
                                {
                                    continue;
                                }
                                this._testInfos.Remove(item);
                            }
                            TestInfo info3 = new TestInfo {
                                Method = info,
                                Name = attribute.Name,
                                Group = attribute.Path,
                                Order = attribute.Order,
                                ExecutionOrder = attribute.ExecutionOrder,
                                Id = attribute.Id,
                                Category = attribute.Category,
                                Version = attribute.Version,
                                RequirementLevel = attribute.RequirementLevel
                            };
                            info3.RequiredFeatures.AddRange(attribute.RequiredFeatures);
                            info3.FunctionalityUnderTest.AddRange(attribute.FunctionalityUnderTest);
                            this._testInfos.Add(info3);
                            if (attribute.ParametersTypes != null)
                            {
                                foreach (System.Type type in attribute.ParametersTypes)
                                {
                                    if (!this._settingsTypes.Contains(type))
                                    {
                                        this._settingsTypes.Add(type);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        public void Pause()
        {
            switch (this._td.State)
            {
                case TestState.Idle:
                    break;

                case TestState.Running:
                    this._td.Pause();
                    return;

                case TestState.Paused:
                    this._td.Resume();
                    base.View.SwitchToState(TestTool.GUI.Enums.ApplicationState.TestRunning);
                    break;

                default:
                    return;
            }
        }

        private void ReportTestSuiteCompleted()
        {
            if ((this._testsCount > 1) || !this._runningSingle)
            {
                base.View.ReportTestSuiteCompleted();
            }
        }

        private void ReportTestSuiteStarted(TestSuiteParameters parameters, bool conformance)
        {
            if (this.TestSuiteStarted != null)
            {
                this.TestSuiteStarted(parameters, conformance);
            }
        }

        public void Run(TestSuiteParameters parameters)
        {
            if (base.View.ProfilesView != null)
            {
                base.View.ProfilesView.ClearProfiles();
            }
            this.RunDiagnostic(parameters, false);
        }

        public void RunAll()
        {
            this._td.ResetFeatures();
            this.Clear(true);
            if (base.View.TestTreeView != null)
            {
                base.View.TestTreeView.SelectTests(new TestInfo[0]);
            }
            TestSuiteParameters parameters = this.GetParameters();
            parameters.DefineProfiles = true;
            this.RunDiagnostic(parameters, false);
        }

        public void RunConformance()
        {
            this._td.ResetFeatures();
            this.Clear(true);
            base.View.TestTreeView.SelectTests(new TestInfo[0]);
            TestSuiteParameters parameters = this.GetParameters();
            parameters.AllTestCases.Clear();
            parameters.AllTestCases.AddRange(from TI in this._testInfos
                orderby TI.ExecutionOrder, TI.Category, TI.Order
                select TI);
            parameters.DefineProfiles = true;
            parameters.Profiles.AddRange(this._onvifProfiles);
            parameters.Conformance = true;
            this._runningSingle = false;
            this.InternalRun(parameters, false, true);
        }

        public void RunConformanceSilent(TestSuiteParameters parameters)
        {
            this._td.ResetFeatures();
            this.Clear(true);
            parameters.AllTestCases.Clear();
            parameters.AllTestCases.AddRange(from TI in this._testInfos
                orderby TI.ExecutionOrder, TI.Category, TI.Order
                select TI);
            parameters.Operator = new SilentOperator();
            parameters.VideoForm = null;
            parameters.DefineProfiles = true;
            parameters.Profiles.AddRange(this._onvifProfiles);
            parameters.Conformance = true;
            this._runningSingle = false;
            this.InternalRun(parameters, false, true);
        }

        private void RunDiagnostic(TestSuiteParameters parameters, bool single)
        {
            parameters.AllTestCases.AddRange(from TI in this._testInfos
                orderby TI.ExecutionOrder, TI.Category, TI.Order
                select TI);
            parameters.Profiles.AddRange(this._onvifProfiles);
            this._runningSingle = single;
            this._testsCount = parameters.TestCases.Count;
            parameters.Operator = new Operator(base.View.Window);
            if (this._td.FeaturesDefined)
            {
                parameters.Features.AddRange(this._td.Features);
                parameters.Features.AddRange(this._td.UndefinedFeatures);
            }
            this.InternalRun(parameters, single, false);
        }

        public void RunSingle(TestSuiteParameters parameters)
        {
            if (base.View.ProfilesView != null)
            {
                base.View.ProfilesView.ClearProfiles();
            }
            this.RunDiagnostic(parameters, true);
        }

        public void Save(string fileName, TestResult results)
        {
            this.SaveInternal<TestResult>(fileName, results);
        }

        public void Save(string fileName, List<TestResult> results)
        {
            this.SaveInternal<List<TestResult>>(fileName, results);
        }

        private void SaveInternal<T>(string fileName, T results)
        {
            StreamWriter writer = null;
            try
            {
                DebugReport<T> o = new DebugReport<T> {
                    ExecutionTime = DateTime.Now
                };
                DeviceInfo info = new DeviceInfo();
                if ((this._initializationData != null) && (this._initializationData.DeviceInformation != null))
                {
                    info.FirmwareVersion = this._initializationData.DeviceInformation.FirmwareVersion;
                    info.HardwareID = this._initializationData.DeviceInformation.HardwareID;
                    info.Manufacturer = this._initializationData.DeviceInformation.Manufacturer;
                    info.Model = this._initializationData.DeviceInformation.Model;
                    info.SerialNumber = this._initializationData.DeviceInformation.SerialNumber;
                }
                o.DeviceInfo = info;
                o.Results = results;
                ManagementSettings managementSettings = ContextController.GetManagementSettings();
                o.ManagementSettings = managementSettings;
                writer = new StreamWriter(fileName);
                new XmlSerializer(typeof(DebugReport<T>)).Serialize((TextWriter) writer, o);
            }
            catch (Exception exception)
            {
                base.View.ShowError(exception);
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }

        public override void Stop()
        {
            this._td.Stop();
        }

        public override void UpdateContext()
        {
            TestOptions options = new TestOptions();
            if (base.View.TestTreeView != null)
            {
                foreach (TestInfo info in base.View.TestTreeView.SelectedTests)
                {
                    options.Tests.Add(info.Order);
                }
                options.Groups.AddRange(base.View.TestTreeView.SelectedGroups);
            }
            options.Repeat = base.View.Repeat;
            ContextController.UpdateTestOptions(options);
        }

        public void UpdateTestLog()
        {
            TestTool.GUI.Data.TestLog log = new TestTool.GUI.Data.TestLog {
                TestResults = this._testResults,
                Features = this._td.Features,
                TestExecutionTime = this._testExecutionTime,
                InitializationData = this._initializationData,
                FeaturesDefinitionLog = this._featureDefinitionLog
            };
            ContextController.UpdateTestLog(log);
        }

        public override void UpdateViewFunctions()
        {
            DiscoveredDevices discoveredDevices = ContextController.GetDiscoveredDevices();
            bool enable = (discoveredDevices != null) && !string.IsNullOrEmpty(discoveredDevices.ServiceAddress);
            base.View.EnableTestRun(enable);
        }

        private void WriteLog(string entry, LogEntryLevel level)
        {
            string str = string.Empty;
            switch (level)
            {
                case LogEntryLevel.Step:
                    str = "   ";
                    break;

                case LogEntryLevel.StepDetails:
                    str = "      ";
                    break;
            }
            string newValue = Environment.NewLine + str;
            string str3 = string.Format("{0}{1}", str, entry.Replace(Environment.NewLine, newValue));
            this._plainTextLog.AppendLine(str3);
            if ((level == LogEntryLevel.Test) || (level == LogEntryLevel.Step))
            {
                this._shortTestLog.AppendLine(str3);
            }
            this.DisplayLogLine(str3);
        }

        public List<System.Type> AdvancedSettingsTypes
        {
            get
            {
                return this._settingsTypes;
            }
        }

        public TestInfo CurrentTest
        {
            get
            {
                return this._td.CurrentTest;
            }
        }

        public TestTool.Tests.Engine.DeviceInformation DeviceInformation
        {
            get
            {
                if (this._initializationData == null)
                {
                    return null;
                }
                return this._initializationData.DeviceInformation;
            }
        }

        public bool FeaturesDefined
        {
            get
            {
                return this._td.FeaturesDefined;
            }
        }

        public bool Running
        {
            get
            {
                return this._running;
            }
        }

        public bool ScrollingEnabled
        {
            get
            {
                return this._scrollingEnabled;
            }
        }

        public TestState State
        {
            get
            {
                return this._td.State;
            }
        }

        public List<TestInfo> TestInfos
        {
            get
            {
                return this._testInfos;
            }
        }
    }
}

